#include <stdlib.h>
#include <stdio.h>

int main()
{
    int row = 0;
    int col = 0;
    int min_row = 0; // 行前缀和的最小值
    int min_col = 0; // 列前缀和的最小值

    // 读取行和列的值
    scanf("%d%d", &row, &col);
    // 动态分配数组a(横)和b(纵)的空间
    int *sum_row = (int *)malloc(sizeof(int) * row);
    int *sum_col = (int *)malloc(sizeof(int) * col);

    // 初始化数组a和b
    for (int i = 0; i < row; i++)
    {
        sum_row[i] = 0;
    }
    for (int i = 0; i < col; i++)
    {
        sum_col[i] = 0;
    }

    // 读取区块权值并计算每行和每列的总权值
    for (int i = 0; i < row; i++)
    {
        for (int j = 0; j < col; j++)
        {
            int element;
            scanf("%d", &element);
            sum_row[i] += element; // sum_row[0]表示第 0 行的和
            sum_col[j] += element; // sum_col[0]表示第 0 列的和
        }
    }

    // 计算每列以及每行的前缀和
    for (int i = 1; i < row; i++)
    {
        sum_row[i] += sum_row[i - 1];
    }
    for (int i = 1; i < col; i++)
    {
        sum_col[i] += sum_col[i - 1];
    }

    // 初始化min_row和min_col为最大可能值
    min_row = sum_row[row - 1];
    min_col = sum_col[col - 1];

    // 计算按行划分的最小差异
    int split_row = 0;
    while (split_row < row)
    {
        min_row = (min_row > abs(sum_row[row - 1] - 2 * sum_row[split_row])) ?  abs(sum_row[row - 1] - 2 * sum_row[split_row]) : min_row;
        // 原理同列，但更高级
        split_row ++;
    }
    // 计算按列划分的最小差异
    int split_col = 0;
    while (split_col < col)
    {
        if (min_col > abs(sum_col[col - 1] - 2 * sum_col[split_col]))
        {
            min_col = abs(sum_col[col - 1] - 2 * sum_col[split_col]);
        }
        split_col ++;
    }

    // 输出最小差异
    printf("%d\n", (min_row <= min_col) ? min_row : min_col);

    // 释放分配的内存
    free(sum_row);
    free(sum_col);
    return 0;
}
